<script setup>
import { markRaw, onMounted, onUnmounted, reactive, ref, computed } from "vue";
import { useRouter } from "vue-router";
import axios from "axios";
import * as echarts from "echarts/core";
import { TreemapChart } from "echarts/charts";
import { CanvasRenderer } from "echarts/renderers";
import { TitleComponent, TooltipComponent } from "echarts/components";
import { interpolatedColor } from "@/utils/utils.js";
import {
  getColorConfig,
  getColorTime,
  getColorArea,
  getColorValue,
  getZhiShu,
  loginOut,
  getVipList,
  getVipDetail,
  getLoginSession,
} from "@/apis/index.js";
import { clearLocalStorage } from "@/utils/request.js";
import { useStockMarketStatus } from "@/hooks/useStockMarketStatus.js";
import { ElMessage, ElMessageBox } from "element-plus";
import { UserFilled } from "@element-plus/icons-vue";
import LoginModal from "@/components/LoginModal.vue";
import VipModal from "@/components/VipModal.vue";

import { Filter } from "@element-plus/icons-vue";

// 注册必须的组件
echarts.use([TitleComponent, TooltipComponent, TreemapChart, CanvasRenderer]);

const { isMarketOpen } = useStockMarketStatus();

const router = useRouter();
const state = reactive({
  select: "",
  replayVal: "",
  classifyDateValue: "",
  dateClassify: "",
  img: {
    src: "",
  },
  isLogin: false,
  showFull: false,
  modalVisible: false,
  vipModalVisible: false,
  loginModalVisible: false,
  params: {
    class: "",
    area: "",
    date: "",
    tspan: "",
    colorv: "",
    htime: "",
  },
  liuTongParams: {},
  zhangdieParams: {},
  percentageData: {},
  colorConfig: {
    t: "",
    v: [],
    msg: "",
    ftime: "",
  },
  vipList: [],
  auto: [],
  colorRanges: [
    { range: -4, color: "#28d742" },
    { range: -3, color: "#1da548" },
    { range: -2, color: "#106f2f" },
    { range: -1, color: "#0a5421" },
    { range: 0, color: "#424454" },
    { range: 1, color: "#6d1414" },
    { range: 2, color: "#960f0f" },
    { range: 3, color: "#be1207" },
    { range: 4, color: "#e41813" },
  ],
  zhiShuData: [],
  zhiShuDataGroup: [],
  replayData: [
    {
      id: 1,
      label: "0930",
      value: "9:30",
    },
    {
      id: 2,
      label: "1000",
      value: "10:00",
    },
    {
      id: 3,
      label: "1030",
      value: "10:30",
    },
    {
      id: 4,
      label: "1100",
      value: "11:00",
    },
    {
      id: 5,
      label: "1130",
      value: "11:30",
    },
    {
      id: 6,
      label: "1330",
      value: "13:30",
    },
    {
      id: 7,
      label: "1400",
      value: "14:00",
    },
    {
      id: 8,
      label: "1430",
      value: "14:30",
    },
    {
      id: 9,
      label: "1500",
      value: "15:00",
    },
  ],
  dateClassifyOptions: [
    {
      value: 1,
      label: "日历",
    },
    {
      value: 2,
      label: "月度简洁日历",
    },
  ],
  classifyDateOptions: [
    {
      value: 1,
      label: "日期时间",
    },
    {
      value: 5,
      label: "附近5日",
    },
    {
      value: 10,
      label: "附近10日",
    },
    {
      value: 20,
      label: "附近20日",
    },
    {
      value: 40,
      label: "附近40日",
    },
    {
      value: 60,
      label: "附近60日",
    },
    {
      value: 100,
      label: "日期当年",
    },
    {
      value: 250,
      label: "附近1年",
    },
    {
      value: 500,
      label: "附近2年",
    },
  ],
});
const info = ref([
  {
    name: "分类选项",
    value: null,
    type: "class",
    page: 1,
    checkedList: [
      {
        name: "A股全部",
        value: "all",
      },
      {
        name: "上证A股",
        value: "sh",
      },
      {
        name: "深证A股",
        value: "sz",
      },
      {
        name: "创业板股",
        value: "cy",
      },
      {
        name: "科创板股",
        value: "kc",
      },
      {
        name: "北交所股",
        value: "bj",
      },
    ],
  },
  {
    name: "面积选项",
    value: null,
    type: "area",
    bg: "#4d4d4d",
    page: 1,
    checkedList: [
      {
        name: "流通市值",
        value: "liutong",
      },
      {
        name: "总市值",
        value: "shiizhi",
      },
      {
        name: "成交额",
        value: "chengjiao",
      },
      {
        name: "净资金流",
        value: "fund",
      },
      {
        name: "中资金流",
        value: "fundmiddle",
      },
      {
        name: "大资金流",
        value: "fundbig",
      },
    ],
  },
  {
    name: "颜色选项",
    value: null,
    type: "colorv",
    page: 1,
    checkedList: [
      {
        name: "涨跌比",
        value: "zhangdie",
      },
      {
        name: "换手率",
        value: "huanshou",
      },
      {
        name: "净金流比",
        value: "fund",
      },
      {
        name: "中金流比",
        value: "fundmiddle",
      },
      {
        name: "大金流比",
        value: "fundbig",
      },
      {
        name: "市盈率",
        value: "ttm",
      },
      {
        name: "市净率",
        value: "pbr",
      },
    ],
  },
]);
const showFilter = ref(false);
let echartsData = ref([]);
let myChart = reactive(null);
let timer = ref(null);
let ftime = ref(0);
let option = ref(null);

onMounted(async () => {
  state.isLogin = !!localStorage.getItem("isLogin");
  await handleGetZhiShu();
  await handleGetColorConfig();
  await initEcharts();
});

onUnmounted(() => {
  if (timer.value) {
    clearInterval(timer.value);
  }
  if (myChart) {
    myChart.dispose();
  }
});
// 控制筛选面板显示
const toggleFilter = () => {
  showFilter.value = !showFilter.value;
};
/**
 * @description 将原始数据转换为echarts需要的数据格式
 * @param data
 * @return {{parent: string, code: string, children: *[], link, name: *, scale: number}}
 */
const transformJson = (data) => {
  const result = {
    code: String(data.code),
    parent: String(data.parent),
    scale: Number(data.scale),
    link: data.link,
    name: data.name ? data.name : data.children.name,
    children: [],
  };

  if (data.children) {
    for (const key in data.children) {
      if (typeof data.children[key] === "object") {
        result.children.push(transformJson(data.children[key]));
      }
    }
  }
  return result;
};
/**
 * 更新图表辅助函数
 * @param percentageData
 * @param nodes
 * @return {*[]}
 */
function updateNodeData(percentageData, nodes) {
  return nodes.map((node) => {
    const newNode = { ...node }; // 创建节点的副本
    if (newNode.children) {
      newNode.children = updateNodeData(percentageData, newNode.children);
      // 更新父节点的边框颜色
      if (newNode.children.length > 0) {
        newNode.itemStyle = {
          borderColor: newNode.children[0].itemStyle.color,
        };
      }
      // console.log("当前数据code", newNode);
    }
    if (newNode.code && !newNode.children.length) {
      const { price, percentage } = getPercentage(newNode.code, percentageData);
      if (percentage !== null) {
        newNode.percentage = percentage;
        newNode.price = price;
        newNode.itemStyle = {
          color: getColor(percentage),
        };
      }
    }
    return newNode;
  });
}
/**
 * 定时刷新图表
 * @return {Promise<void>}
 */
const updateChartData = async () => {
  try {
    const percentageData = await getColorValue(state.params);
    // 获取当前的系列数据
    const currentSeriesData = option.value.series[0].data;
    // 更新数据但保持结构不变
    echartsData.value = updateNodeData(percentageData.data, currentSeriesData);
    // myChart.setOption({
    //   series: [{
    //     data: updatedData
    //   }]
    // },true);
    // option.series[0].data = updatedData;
    option.value.series[0].data = echartsData.value;
    myChart.setOption({
      series: [
        {
          data: echartsData.value,
        },
      ],
    });
    await handleGetZhiShu();
    // var nodeId = "0"; // 替换为你想要展开或折叠的节点的 ID
    // myChart.dispatchAction({
    //   type: "treemapRootToNode",
    //   targetNodeId: nodeId,
    //   direction: "drillDown", // 或 'rollUp'，取决于你想要展开还是折叠节点
    // });
    //   series: {
    //     data: updatedData
    //   }
    // });
  } catch (error) {
    console.error("Failed to update data:", error);
  }
};
/**
 * 初始化echarts
 * @link 矩形树图配置项 https://echarts.apache.org/zh/option.html#series-treemap
 * @return {Promise<{verticalAlign: string, align: string}>}
 */
const initEcharts = async () => {
  let chartDom = document.getElementById("echarts");
  myChart = markRaw(
    echarts.init(chartDom, null, {
      useDirtyRect: true,
    }),
  );
  myChart.showLoading();
  try {
    const [diskData, percentageData] = await Promise.all([
      getColorArea(state.params),
      getColorValue(state.params),
    ]);

    const transformedData = transformJson(diskData.data);

    if (percentageData.data.length !== 0) {
      state.percentageData = percentageData.data;
    }
    echartsData.value = processTreemapData(
      transformedData.children,
      state.percentageData,
    );
    const codeMap = new Map();

    myChart.hideLoading();

    function getLevelOption() {
      return [
        {
          itemStyle: {
            gapWidth: 1,
          },
          upperLabel: {
            show: false,
          },
        },
        {
          itemStyle: {
            borderColor: "#000",
            borderWidth: 1,
            gapWidth: 0.8,
          },
        },
        {
          itemStyle: {
            borderColor: "#000",
            borderWidth: 2,
            gapWidth: 0,
            borderColorSaturation: 0.5,
          },
          emphasis: {
            itemStyle: {
              borderColor: "#FED514",
            },
          },
        },
        {
          color: [], //颜色
          itemStyle: {
            borderColor: "#000",
            borderWidth: 0.5,
            gapWidth: 0,
          },
          emphasis: {
            itemStyle: {
              borderColor: "#FED514",
            },
          },
        },
      ];
    }

    option.value = {
      type: "treemap",
      tooltip: {
        borderColor: "#000",
        borderWidth: 4,
        padding: 0,
        position: function (point, params, dom, rect, size) {
          // 鼠标坐标和提示框位置的参考坐标系是：以外层div的左上角那一点为原点，x轴向右，y轴向下
          // 提示框位置
          let x = 0; // x坐标位置
          let y = 0; // y坐标位置

          // 当前鼠标位置
          let pointX = point[0];
          let pointY = point[1];

          // 提示框大小
          let boxWidth = size.contentSize[0];
          let boxHeight = size.contentSize[1];
          // boxWidth > pointX 说明鼠标左边放不下提示框
          if (boxWidth + 30 > pointX) {
            x = pointX + 30;
          } else {
            // 左边放的下
            x = pointX - boxWidth - 30;
          }

          // boxHeight > pointY 说明鼠标上边放不下提示框
          if (boxHeight > pointY) {
            y = 5;
          } else {
            // 上边放得下
            y = pointY - boxHeight;
          }

          return [x, y];
        },
        formatter: function (params, a) {
          if (params.treeAncestors.length <= 2) {
            return;
          }
          echartsData.value.forEach((item) => {
            item.children.forEach((child) => {
              codeMap.set(child.code, child);
            });
          });
          const parent = codeMap.get(params.data.parent);

          const list = params.data.children.length
            ? params.data.children
            : parent.children;
          const treePathInfo = params.treePathInfo;
          const parentTitle1 = treePathInfo[treePathInfo.length - 2].name;
          const parentTitle2 = treePathInfo[treePathInfo.length - 1].name;
          const parentTitleNode = `<div class="tooltip-title">${parentTitle1}-${parentTitle2}</div>`;
          const randomStr = Math.random();
          // 在list中找出code == params.code 的数据并将其排到第一位
          list.sort((a, b) => {
            return a.code === params.data.code ? -1 : 1;
          });

          const childrenSection = list
            ?.map((child, index) => {
              const codeStr = child.code.split(".");
              if (index === 0) {
                return `
              <div class="tooltip-item_title tooltip-item"
                style="background-color:${params.borderColor !== "#000" ? params.borderColor : child.itemStyle.color}"
                >
                <span>${child.name}</span>
                 <span class="tooltip-item_price">${child.price}</span>
                <span class="tooltip-item_percentage">${child.percentage > 0 ? `+${child.percentage}` : child.percentage}%</span>
             </div>
             <img class="tooltip-item_kImage" src="http://image.sinajs.cn/newchart/daily/n/${codeStr[1].toLowerCase()}${codeStr[0]}.gif?${randomStr}"
              alt = "空" />
                <div class="tooltip-item" style="background: #1677ff;color: white;">
                <span class="tooltip-item_name" style="color: white;">股票名字</span>
                <span class="tooltip-item_price">股价</span>
                <span class="tooltip-item_percentage">涨跌幅</span>
                </div>
                `;
              }

              return `<div class="tooltip-item">
                <span class="tooltip-item_name" >${child.name}</span>
                <span class="tooltip-item_price"  style="color:${child.itemStyle.color}">${child.price}</span>
                <span class="tooltip-item_percentage" style="color:${child.itemStyle.color}">${child.percentage > 0 ? `+${child.percentage}` : child.percentage}%</span></div>`;
            })
            .join("");
          return [parentTitleNode, childrenSection].filter(Boolean).join("");
        },
        extraCssText: "box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);",
      },

      // dataset: {
      //   dimensions: ["name", "value", "children"],
      //   source: [echartsData.value],
      // },
      series: [
        {
          type: "treemap",
          width: "100%",
          height: "100%",
          animation: false, // 禁用动画
          top: "0",
          // sampling: 'average',//' 表示采用平均值采样策略
          // large: true,
          // largeThreshold: 100,
          roam: true,
          scaleLimit: {
            min: 1,
            max: 6,
          },
          nodeClick: "link",
          breadcrumb: {
            show: false,
          },
          // labelLayout: {
          //   verticalAlign: "middle",
          //   align: "center",
          // },
          // 渐进渲染相关
          // progressive: 500, // 每次渲染200个矩形
          // progressiveThreshold: 1000, // 超过1000个数据项时启用渐进式渲染

          // 动画相关
          // animation: true,
          // animationDurationUpdate: 500, // 更新动画duration设短一点

          // 布局相关
          // leafDepth: 2, // 设置展示层级,避免一次性展示过多
          // drillDownIcon: "▶", // 可钻取节点图标

          // 增量更新相关
          // incrementalUpdate: true, // 启用增量更新
          label: {
            show: true,
            align: "center",
            overflow: "truncate",
            ellipsis: "",
            fontSize: 8.5,
            lineHeight: 10,
            // minSize: 9,
            formatter: function (params) {
              // console.log(params);
              if (params.data.percentage) {
                return `${params.name}\n${params.data.percentage > 0 ? `+${params.data.percentage}` : params.data.percentage}%`;
              }
              return params.name;
            },
          },
          itemStyle: {
            borderColor: "#fff",
            gapWidth: 5,
          },
          upperLabel: {
            show: true,
            height: 20,
            color: "#fff",
          },
          levels: getLevelOption(),
          data: echartsData.value,
        },
      ],
    };
    myChart.setOption(option.value);
    window.onresize = myChart.resize;
    if (timer.value) {
      clearInterval(timer.value);
    }
    state.isLogin = !!localStorage.getItem("isLogin");
    if (diskData.data.mcode != 100 && diskData.data.mmsg) {
      ElMessage({
        message: diskData.data.mmsg,
        grouping: true,
        offset: window.screen.height / 3,
        customClass: "bai-message",
        type: "warning",
      });
    }
    switch (diskData.data.mcode) {
      case 100:
        if (isMarketOpen.value && ftime.value !== 0) {
          timer.value = setInterval(updateChartData, ftime.value);
        }
        break;
      case 200:
        state.loginModalVisible = true;
        break;
      case 300:
        await handleOpenVipModal();
        break;
      default:
        break;
    }
  } catch (error) {
    console.error("Failed to initialize chart:", error);
    myChart.hideLoading();
  }
};
/**
 * 获取指数数据
 * @return {Promise<void>}
 */
const handleGetZhiShu = async () => {
  const { data } = await getZhiShu();
  if (state.zhiShuDataGroup.length === 0) {
    data.forEach((item, index) => {
      if (index % 5 === 0) {
        state.zhiShuDataGroup.push([]);
      }
      state.zhiShuDataGroup[Math.floor(index / 5)].push(item);
    });
  } else {
    data.forEach((newItem) => {
      state.zhiShuDataGroup.forEach((group) => {
        const itemIndex = group.findIndex(
          (item) => item.indexCode === newItem.indexCode,
        );
        if (itemIndex !== -1) {
          group[itemIndex] = newItem;
        }
      });
    });
  }
};
/**
 * 获取颜色配置
 * @return {Promise<void>}
 */
const handleGetColorConfig = async () => {
  const { data } = await getColorConfig(state.params);
  state.colorConfig = data;
  if (timer.value) {
    clearInterval(timer.value);
  }
  ftime.value = data.ftime * 1000;
  state.colorRanges.forEach((item, index) => {
    item.range = data.v[index];
  });
};
/**
 * 获取股票价格 涨跌幅
 * @param code 股票代码
 * @param percentageData 涨跌幅数据
 * @return {{price: string, percentage: string}|null}
 */
const getPercentage = (code, percentageData) => {
  if (!code || !percentageData[code]) return null;
  const price = percentageData[code].split("|")[0];
  const percentage = percentageData[code].split("|")[1];
  return {
    price: price,
    percentage: percentage,
  };
};
const isAfterTime = (hour, minutes) => {
  const now = new Date();
  const target = new Date(now.setHours(hour, minutes, 0, 0));
  return new Date() >= target;
};
/**
 * 复盘当日数据
 * @param htime 复盘时间
 * @return {Promise<void>}
 */
const handleGetColorTime = async (htime, ctime, id) => {
  if (state.replayVal === id) {
    state.replayVal = "";
    state.params.htime = "";
    await handleRefresh();
    return;
  }
  const hour = ctime.split(":")[0];
  const minutes = Number(ctime.split(":")[1]);
  if (!isAfterTime(hour, minutes + 1)) {
    ElMessage({
      message: `${ctime}后才可以复盘此时间交易`,
      grouping: true,
      offset: window.screen.height / 3,
      customClass: "bai-message",
      type: "warning",
    });
    return;
  }
  try {
    state.replayVal = id;
    state.params.htime = htime;
    const { data } = await getColorTime(state.params);
    await handleGetColorConfig();

    // 获取当前的系列数据
    const currentSeriesData = option.value.series[0].data;
    // 更新数据但保持结构不变
    echartsData.value = updateNodeData(data, currentSeriesData);
    option.value.series[0].data = echartsData.value;
    myChart.setOption({
      series: [
        {
          data: echartsData.value,
        },
      ],
    });
    // console.log(data);
  } catch (error) {
    ElMessage({
      message: `复盘错误${error}`,
      grouping: true,
      offset: window.screen.height / 3,
      customClass: "bai-message",
      type: "error",
    });
  }
};
/**
 * 合并处理 treemap 数据
 * @param data 数据
 * @param percentageData 涨跌数据
 * @return {*[]} 合并处理后的数据
 */
const processTreemapData = (data, percentageData) => {
  function transformNode(node, level = 0) {
    let result = {
      name: node.name,
      code: node.code,
      parent: node.parent,
      value: node.scale,
      children: node.children,
      itemStyle: node.itemStyle,
    };
    if (node.children && node.children.length > 0) {
      result = {
        name: node.name,
        code: node.code,
        value: node.scale,
        parent: node.parent,
        link: node.link,
        children: node.children.map((child) => transformNode(child, level + 1)),
      };
      result.itemStyle = {
        borderColor: result.children[0].itemStyle.color,
      };
    } else if (node.code) {
      const { price, percentage } = getPercentage(node.code, percentageData);
      if (percentage !== null) {
        result.price = price;
        result.link = `https://xueqiu.com/S/${result.code.split(".")[1]}${result.code.split(".")[0]}`;
        result.percentage = percentage;
        result.itemStyle = {
          color: getColor(percentage),
        };
      }
    }

    return result;
  }

  return data.map((item) => ({
    name: item.name,
    children: item.children
      ? item.children.map((child) => transformNode(child, 0))
      : [],
  }));
};

/**
 * 获取颜色
 * @param percentage 数据值，用于计算颜色
 * @return {string|null} 颜色值
 */
const getColor = (percentage) => {
  return interpolatedColor(state.colorRanges, percentage);
  // for (const item of colorMap) {
  //   if (
  //     (item.range === ">=4" && percentage >= 4) ||
  //     (item.range === ">=3" && percentage >= 3) ||
  //     (item.range === ">=2" && percentage >= 2) ||
  //     (item.range === ">=1" && percentage >= 1) ||
  //     (item.range === "<=-4" && percentage <= -4) ||
  //     (item.range === "<=-3" && percentage <= -3) ||
  //     (item.range === "<=-2" && percentage <= -2) ||
  //     (item.range === "<=-1" && percentage <= -1) ||
  //     (item.range === "<=0" && percentage <= 0)
  //   ) {
  //     return item.color;
  //   }
  // }
};

/**
 * 全屏echarts
 */
const handleFull = () => {
  const element = document.getElementById("echarts");
  myChart.resize();
  state.showFull = true;
  if (element.requestFullScreen) {
    element.requestFullScreen();
  } else if (element.msRequestFullscreen) {
    // IE11
    element.msRequestFullScreen();
  } else if (element.webkitRequestFullScreen) {
    // Webkit (works in Safari5.1 and Chrome 15)
    element.webkitRequestFullScreen();
  } else if (element.mozRequestFullScreen) {
    // Firefox (works in nightly)
    element.mozRequestFullScreen();
  } else {
    state.showFull = false;
  }
  // 退出全屏
  if (element.requestFullScreen) {
    document.exitFullscreen();
  } else if (element.msRequestFullScreen) {
    document.msExitFullscreen();
  } else if (element.webkitRequestFullScreen) {
    document.webkitCancelFullScreen();
  } else if (element.mozRequestFullScreen) {
    document.mozCancelFullScreen();
  }
};

/**
 * 导出图表
 * @constructor
 */
function Export() {
  // const { data } = await getColorConfig(state.params);
  // state.colorConfig = data;
  const img = new Image();
  // title: {
  //   text: "数据来源 https://tu.h0.cn",
  //       left: "center",
  // },
  img.src = myChart.getDataURL({
    type: "png",
    pixelRatio: 2, //放大2倍
    backgroundColor: "#fff",
  });
  img.onload = function () {
    const canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height + 160;
    const ctx = canvas.getContext("2d");

    // 1. 先绘制图片
    ctx.drawImage(img, 0, 80);

    ctx.fillStyle = "#AF0000";
    ctx.fillRect(0, 0, img.width, 80);

    // 3. 设置文字样式并居中
    const text = state.colorConfig.msgpic;
    ctx.font = "30px Arial"; // 添加 bold 使文字加粗
    ctx.fillStyle = "#fff";
    ctx.textAlign = "center"; // 设置文字水平居中
    ctx.textBaseline = "middle"; // 设置文字垂直居中
    // 在画布宽度的中点绘制文字
    ctx.fillText(text, canvas.width / 2, 40);
    //添加文字 大小占满高度
    const text2 = "tu.h0.cn";
    ctx.font = "70px Arial";
    ctx.fillText(text2, canvas.width / 1.1, 40);

    state.img.src = canvas.toDataURL("image/png");
  };
  state.modalVisible = true;
}

/**
 * 下载echarts截图生成的图片
 */
const handleDownload = () => {
  const a = document.createElement("a");
  const event = new MouseEvent("click");
  a.download = "图片.png" || "下载图片名称";
  a.href = state.img.src;
  a.dispatchEvent(event);
  a.remove();
  state.modalVisible = false;
};
/**
 * 处理分页数组
 * @param list 要分页的数组
 * @param page 页码
 * @return {*[]} 分页后的数组
 */
const currentPageItems = (list, page) => {
  const start = (page - 1) * 6;
  const end = start + 6;
  return list.slice(start, end);
};
/**
 *  上一页
 * @param index 在父数组中的标识
 * @param list 要分页的数组
 */
const handlePrevPage = (index, list) => {
  if (info.value[index].page <= 1) {
    ElMessage({
      message: "没有更多了~",
      grouping: true,
      offset: window.screen.height / 3,
      customClass: "bai-message",
      type: "warning",
    });
    return;
  }
  info.value[index].page--;
  currentPageItems(list);
};
/**
 * 下一页
 * @param index 在父数组中的标识
 * @param list 要分页的数组
 */
const handleNextPage = (index, list) => {
  if (info.value[index].page >= list.length / 6) {
    ElMessage({
      message: "没有更多了~",
      grouping: true,
      offset: window.screen.height / 3,
      customClass: "bai-message",
      type: "warning",
    });
    return;
  }
  info.value[index].page++;
  currentPageItems(list);
};

/**
 * 头部选择类型
 * @param value 选中值
 * @param item  循环值
 */
const handleSelect = (value, item) => {
  if (value === item.value) {
    state.params[item.type] = "";
    item.value = "";
    return;
  }
  state.params[item.type] = value;
  item.value = value;
};
/**
 * 确认刷新按钮 提交参数
 * @return {Promise<void>}
 */
const handleRefresh = async () => {
  // state.replayVal = "";
  showFilter.value = false;
  state.auto = [];
  state.auto.push(state.params.colorv, state.classifyDateValue ? "time" : null);
  console.log(
    handlePermission(state.auto, [
      "pbr",
      "ttm",
      "fundbig",
      "fundmiddle",
      "fund",
      "time",
    ]).value,
  );
  state.replayVal = "";
  state.params.htime = "";
  state.params.date = state.dateClassify;
  state.params.tspan = state.classifyDateValue;
  await handleGetColorConfig();
  await initEcharts();
};
/**
 * 判断权限
 * @return {ComputedRef<boolean>}
 */
const handlePermission = (auto, permission) => {
  return computed(() => {
    return !auto.some((item) => permission.includes(item));
  });
};

//刷新页面
const handleRefreshPage = async () => {
  window.location.reload();
};
/**
 * 登录
 */
const handleLoginSubmit = () => {
  state.isLogin = !!localStorage.getItem("isLogin");
};
//打开会员弹窗
const handleOpenVipModal = async () => {
  state.vipModalVisible = true;
};

//退出登录
const handleQuitLogin = () => {
  ElMessageBox.confirm("确定退出登录？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      await clearLocalStorage();
    })
    .catch(() => {});
};
</script>

<template>
  <div class="box w-full">
    <div
      class="w-full grid justify-items-start"
      style="border-bottom: 1px solid #e6e7eb; background-color: #2d2d2d"
    >
      <!-- 主要内容区域 -->
      <div class="w-full grid justify-items-start sm:flex items-center">
        <!-- Logo + 滚动区域 -->
        <div class="flex flex-col sm:flex-row w-full sm:w-auto">
          <!-- Logo区域 -->
          <div class="flex items-center justify-between w-full sm:w-auto">
            <div @click="handleRefreshPage" class="flex items-center">
              <img
                src="@/assets/images/logo.png"
                alt="logo"
                class="w-[50px] sm:w-[70px]"
              />
            </div>
            <!-- 移动端触发筛选按钮 -->
            <div class="sm:hidden">
              <el-button @click="toggleFilter" size="small">
                <el-icon><Filter /></el-icon>
              </el-button>
            </div>
          </div>

          <!-- 行情滚动区域 -->
          <div class="w-full my-auto sm:w-80">
            <el-carousel
              v-if="state.zhiShuDataGroup.length"
              height="50px"
              sm:height="70px"
              indicator-position="none"
              :autoplay="true"
            >
              <el-carousel-item
                v-for="item in state.zhiShuDataGroup"
                :key="item"
              >
                <div class="w-full h-full flex gap-2 flex-center">
                  <div
                    v-for="item1 in item"
                    :key="item1.indexName"
                    class="flex flex-col flex-center gap-0.5"
                  >
                    <span class="font-bold text-white text-xs sm:text-sm">
                      {{ item1.indexName }}
                    </span>
                    <span
                      class="text-xs"
                      :style="{
                        color: item1.pctChg > 0 ? '#ff0000' : '#4eff00',
                      }"
                    >
                      {{ item1.price }}
                    </span>
                    <span
                      class="text-xs"
                      :style="{
                        color: item1.pctChg > 0 ? '#ff0000' : '#4eff00',
                      }"
                    >
                      {{ item1.pctChg }}{{ item1.pos }}
                    </span>
                  </div>
                </div>
              </el-carousel-item>
            </el-carousel>
          </div>
        </div>

        <!-- 桌面端筛选区域 -->
        <div class="hidden sm:flex">
          <div
            class="flex text-[#ffffff] flex-col h-[70px] justify-start"
            v-for="(item, index) in info"
            :key="index"
          >
            <div
              class="flex justify-center text-xs h-4 px-1 leading-4"
              :style="
                index % 2 === 1
                  ? 'background-color:#1d1d1d'
                  : 'background-color:#000000'
              "
            >
              <div class="flex-center w-[30px]">
                <el-button
                  size="small"
                  circle
                  color="#af0000"
                  class="scale-50 opacity-90"
                  @click="handlePrevPage(index, item.checkedList)"
                >
                  <el-icon class="scale-125"><ArrowLeftBold /></el-icon>
                </el-button>
              </div>
              <div class="scale-75">{{ item.name }}</div>
              <div class="flex-center w-[30px]">
                <el-button
                  size="small"
                  circle
                  color="#af0000"
                  class="scale-50 opacity-90"
                  @click="handleNextPage(index, item.checkedList)"
                >
                  <el-icon class="scale-125"><ArrowRightBold /></el-icon>
                </el-button>
              </div>
            </div>
            <div
              class="h-16 text-xs px-1 grid grid-cols-3 overflow-hidden grid-rows-2 content-center gap-x-1 gap-y-0.5"
              :style="{ background: item.bg ? item.bg : '' }"
            >
              <div
                v-for="(item1, index1) in currentPageItems(
                  item.checkedList,
                  item.page,
                )"
                :key="index1"
              >
                <div
                  class="check-tag cursor-pointer"
                  :class="[
                    item1.value === item.value ? 'check-tag_checked' : '',
                  ]"
                  @click="handleSelect(item1.value, item)"
                >
                  {{ item1.name }}
                </div>
              </div>
            </div>
          </div>
          <div class="ml-3 my-auto flex gap-3 align-center">
            <div class="flex flex-col gap-1">
              <el-date-picker
                v-model="state.dateClassify"
                type="date"
                placeholder="请选择日期"
                size="small"
                value-format="YYYYMMDD"
                style="width: 125px"
              />
              <el-select
                v-model="state.classifyDateValue"
                clearable
                placeholder="请选择时间段"
                size="small"
                style="width: 125px"
              >
                <template #prefix>
                  <img
                    class="w-3"
                    src="@/assets/images/time_period.png"
                    alt=""
                  />
                </template>
                <el-option
                  v-for="item in state.classifyDateOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </div>
            <el-button size="large" color="#af0000" @click="handleRefresh"
              >确认刷新</el-button
            >
          </div>
        </div>

        <!-- 右侧功能区域 -->
        <div class="text-[#ffffff] text-[14px] flex items-center gap-3 ml-auto">
          <!-- 全屏按钮 -->
          <div
            class="sm:flex items-center gap-0.5 cursor-pointer"
            @click="handleFull"
          >
            <span class="hidden sm:inline">全屏</span>
            <img class="w-5" src="@/assets/images/full.png" alt="" />
          </div>

          <!-- 截图分享 -->
          <div class="flex items-center gap-0.5 cursor-pointer" @click="Export">
            <span class="hidden sm:inline">截图</span>
            <img class="w-4" src="@/assets/images/share.png" alt="" />
          </div>

          <!-- 帮助按钮 -->
          <el-popover placement="bottom" width="250" trigger="click">
            <template #reference>
              <div class="cursor-pointer flex items-center gap-0.5">
                <span class="hidden sm:inline">帮助</span>
                <img class="w-4" src="@/assets/images/help.png" alt="" />
              </div>
            </template>
            <template #default>
              <img
                class="w-56 h-[28rem] object-cover"
                src="@/assets/images/group_of.png"
                alt=""
              />
            </template>
          </el-popover>

          <!-- 登录/用户头像 -->
          <div v-if="!state.isLogin">
            <el-button
              class="mr-1"
              color="#af0000"
              @click="state.loginModalVisible = true"
            >
              <span class="hidden sm:inline">注册/登录</span>
              <el-icon v-if="!state.isLogin" class="sm:hidden"
                ><User
              /></el-icon>
            </el-button>
          </div>
          <el-dropdown v-else trigger="click">
            <el-avatar class="mr-1" :icon="UserFilled" />
            <template #dropdown>
              <el-dropdown-menu class="el-bs-size">
                <el-dropdown-item>
                  <div @click.stop="handleOpenVipModal">我的会员</div>
                </el-dropdown-item>
                <el-dropdown-item>
                  <div @click.stop="handleQuitLogin">退出登录</div>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </div>

      <!-- 移动端筛选下拉层 -->
      <el-collapse-transition>
        <div
          v-show="showFilter"
          class="w-[90%] mx-auto mt-2 sm:hidden bg-[#1d1d1d] rounded p-4"
        >
          <!-- 日期选择 -->
          <div class="mb-4">
            <el-date-picker
              v-model="state.dateClassify"
              type="date"
              placeholder="请选择日期"
              size="small"
              value-format="YYYYMMDD"
              class="w-full"
            />
          </div>

          <!-- 时间段选择 -->
          <div class="mb-4">
            <el-select
              v-model="state.classifyDateValue"
              clearable
              placeholder="请选择时间段"
              size="small"
              class="w-full"
            >
              <template #prefix>
                <img class="w-3" src="@/assets/images/time_period.png" alt="" />
              </template>
              <el-option
                v-for="item in state.classifyDateOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>

          <!-- 筛选项组 -->
          <div v-for="(item, index) in info" :key="index" class="mb-4">
            <div class="text-white text-sm mb-2">{{ item.name }}</div>
            <div class="grid grid-cols-3 gap-2">
              <div
                v-for="(option, idx) in item.checkedList"
                :key="idx"
                @click="handleSelect(option.value, item)"
                class="check-tag cursor-pointer text-xs"
                :class="[
                  option.value === item.value ? 'check-tag_checked' : '',
                ]"
              >
                {{ option.name }}
              </div>
            </div>
          </div>

          <!-- 确认按钮 -->
          <el-button class="w-full" color="#af0000" @click="handleRefresh">
            确认筛选
          </el-button>
        </div>
      </el-collapse-transition>
    </div>
    <div class="w-full flex gap-2 overflow-hidden">
      <div class="w-full flex-1">
        <div
          id="echarts"
          style="width: 100%; height: calc(100vh - 120px)"
        ></div>
        <div class="w-full mt-2 flex justify-between flex-col md:flex-row">
          <div
            class="flex flex-wrap justify-start gap-2"
            :class="[
              handlePermission(state.auto, [
                'pbr',
                'ttm',
                'fundbig',
                'fundmiddle',
                'fund',
                'time',
              ]).value
                ? 'visible'
                : 'invisible',
            ]"
          >
            <el-button
              class="ml-0"
              v-for="item in state.replayData"
              :key="item.id"
              size="small"
              style="color: white"
              :color="state.replayVal === item.id ? '#fd0000' : '#e99457'"
              @click="handleGetColorTime(item.label, item.value, item.id)"
            >
              {{ item.value }}
            </el-button>
          </div>
          <div class="text-xs text-slate-400 leading-6">
            {{ state.colorConfig.msg }}
          </div>
          <div class="flex flex-wrap justify-start gap-2">
            <el-button
              class="percentage-color_btn"
              v-for="item in state.colorRanges"
              size="small"
              :color="item.color"
              >{{ item.range }}{{ state.colorConfig.t }}</el-button
            >
            <!--            <el-button size="small" @click="openD3">D3</el-button>-->
          </div>
        </div>
      </div>
    </div>
    <el-dialog v-model="state.modalVisible" title="截图分享">
      <el-image
        style="width: 100%; height: 100%"
        v-if="state.img"
        :src="state.img.src"
        alt=""
        :previewSrcList="[state.img.src]"
        :zoom-rate="1.2"
        :max-scale="7"
        :min-scale="0.2"
      />
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="state.modalVisible = false">取消</el-button>
          <el-button type="primary" @click="handleDownload"> 下载 </el-button>
        </div>
      </template>
    </el-dialog>
    <VipModal v-model="state.vipModalVisible" />
    <LoginModal
      v-model="state.loginModalVisible"
      @save-submit="handleLoginSubmit"
      title="登录"
    />
  </div>
</template>

<style lang="scss">
.check-tag {
  @apply px-2 py-1 text-center rounded bg-[#2d2d2d] text-white;
}

.check-tag_checked {
  @apply bg-[#af0000];
}

/* 移动端样式调整 */
@media (max-width: 640px) {
  .selectnmp {
    @apply hidden;
  }

  .check-tag {
    @apply text-xs px-1;
  }
}
.tooltip-title {
  color: black;
  font-weight: bold;
  padding: 5px 10px;
}
.tooltip-item_title {
  padding: 20px 10px;
  color: white;
  font-size: 18px;
  font-weight: bold;
}
.tooltip-item {
  width: 300px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
}
.tooltip-item_name {
  color: black;
  font-weight: bold;
}
.tooltip-item_price {
  flex: 1;
  text-align: right;
}
.tooltip-item_percentage {
  width: 70px;
  text-align: right;
}
.tooltip-item_kImage {
  width: 270px;
  height: 150px;
  margin: auto;
  display: flex;
}
.percentage-color_btn {
  color: white !important;
}
.selectheight .el-date-editor.el-input,
.selectheight .el-date-editor.el-input__wrapper {
  height: 19px;
}
.selectheight .el-select--small .el-select__wrapper {
  height: 19px;
  min-height: 19px;
}
.selectnmp .el-select--large .el-select__wrapper {
  padding: 8px 6px;
}
.check-tag {
  padding: 3px 6px;
  font-size: 12px;
  font-weight: lighter;
  background-color: rgba($color: #000000, $alpha: 0);
  color: #ffffff;
  position: relative;
}
.check-tag:hover {
  background-color: rgba($color: #000000, $alpha: 0.5);
}
.check-tag_checked {
  color: #ffc94f;
  background-color: rgba($color: #000000, $alpha: 0.5);
}
.check-tag_checked:after {
  content: "";
  background-color: #ffc94f;
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 5px;
  top: 0px;
  right: 0px;
  background-image: url("@/assets/images/check.svg");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: 92%;
}
.el-button + .el-button {
  margin-left: 0 !important;
}
</style>
